package org.hindusingles.thf.server;

import java.text.NumberFormat;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.hindusingles.thf.client.GreetingService;

import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTable;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService
{
	/**
	 * The time zone with which to calculate date differences.
	 */
	private static final TimeZone ZONE = TimeZone.getDefault( );
	
	/**
	 * Parses numbers with comma grouping separators.
	 */
	private static final NumberFormat NUMBER_FORMAT =
	(
		NumberFormat.getInstance( )
	);
	
	/**
	 * Logs information to the console.
	 */
	private static final Logger LOGGER =
	(
		Logger.getLogger
		(
			"org.hindusingles.thf.server.GreetingServiceImpl"
		)
	);
	
	private static final long DEADLINE_MILLIS;
	
	static
	{
		Calendar deadline = Calendar.getInstance(ZONE);
		
		deadline.set(2012, 11, 12);
		
		DEADLINE_MILLIS = deadline.getTimeInMillis( );
	}
	
	private static final int POSTS_GOAL = 1000000;
	
	public String greetServer(String input) throws IllegalArgumentException
	{
		try
		{
			String response = "";
			
			long currentTime = System.currentTimeMillis( );
			currentTime += ZONE.getOffset(currentTime);
			
			long deadline = DEADLINE_MILLIS;
			deadline += ZONE.getOffset(deadline);
			
			response +=
			(
				String.format
				(
					"Deadline: %tB %1$te, %1$tY<br />",
					DEADLINE_MILLIS
				)
			);
			
			long daysLeft =
			(
				TimeUnit.MILLISECONDS.toDays
				(
					deadline - currentTime
				)
			);
			
			response += String.format("Days left: %d<br />", daysLeft);
			
			String postsToDateRaw =
			(
				InsultServlet.client.<HtmlPage>getPage("http://www.thehaloforum.com/misc.php?do=whoposted&t=208561")
					.getBody( ).<HtmlTable>getHtmlElementsByTagName(HtmlTable.TAG_NAME).get(0)
						.getCellAt(0, 0).getHtmlElementsByTagName(HtmlDivision.TAG_NAME).get(0)
							.asText( ).split("Total Posts: ")[1]
			);
			
			int postsToDate = NUMBER_FORMAT.parse(postsToDateRaw).intValue( );
			int postsRemaining = POSTS_GOAL - postsToDate;
			double postsPerDay = (double)postsRemaining / daysLeft;
			
			response += String.format("Goal: %,d posts<br />", POSTS_GOAL);
			response += String.format("To date: %s<br />", postsToDateRaw);
			response += String.format("Remaining: %,d<br />", postsRemaining);
			response += String.format("Per day: %,.2f", postsPerDay);
			
			return response;
		}
		catch (Exception e)
		{
			LOGGER.log
			(
				Level.WARNING,
				"Couldn't parse posts to date.",
				e
			);
			
			throw new IllegalArgumentException("Couldn't get thread stats.", e);
		}
	}
}